package gomysql

import (
	"go-micro-framework/go_service/core/gomodel"
)

type SqlEnumsType string

// 业务增加自定义,这个通用的参数
const (
	SQL_NEW  SqlEnumsType = "NEW"
	SQL_DESC SqlEnumsType = "DESC"
	SQL_ASC  SqlEnumsType = "ASC"
	SQL_ID   SqlEnumsType = "ID" //todo 自定义实现
)

type BaseDao[T any] interface {
	Get() *T
	/** GetId 函数通用实现,获取对象的id值 通过对象获取接口类的GetId()的值 **/
	GetId(entity *T) int64
	/*
		*保存一条记录的方法
		//var user *UserId = &UserId{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
	*/
	Save(entity *T) int64
	/*
		*
		  - 批量保存方法,只返回成功或失败的方法
		    EG: users := []User{
		    User{Name: "Jinzhu", Age: 18, Birthday: time.Now()},
		    User{Name: "Jackson", Age: 19, Birthday: time.Now()},
		    }
	*/
	SaveBatchId(entityList []T, batchSize ...int) *[]int64

	/*
		*
		  - 批量保存方法,只返回成功或失败的方法
		    EG: users := []User{
		    User{Name: "Jinzhu", Age: 18, Birthday: time.Now()},
		    User{Name: "Jackson", Age: 19, Birthday: time.Now()},
		    }
	*/
	SaveBatch(entityList *T, batchSize ...int) bool

	/*
		*保存一条记录的方法,因为没有不会触发 AfterCreate、BeforeCreate 等 hooks（钩子）函数。
		同时，GORM 也不会自动保存关联表的信息，例如外键关联等。此外，GORM 也不会回填主键值。
		//&User{} ,map[string]T{"Name": "jinzhu_Map", "Age": 28,}
	*/
	SaveModel(entity *T, entityKeyValue map[string]any) bool

	/*
	   *
	     - 批量保存方法,并返回列表的主键的方法
	       // batch insert from `[]map[string]T{}`
	       db.Model(&User{}).Create([]map[string]T{
	       {"Name": "jinzhu_1", "Age": 18},
	       {"Name": "jinzhu_2", "Age": 20},
	       })

	   因为没有不会触发 AfterCreate、BeforeCreate 等 hooks（钩子）函数。
	   同时，GORM 也不会自动保存关联表的信息，例如外键关联等。此外，GORM 也不会回填主键值。
	*/
	SaveModelBatch(entity *T, entityKeyValueList map[string]any) bool

	/*** ------------------------删除----------------------------------------- **/

	// DeleteById 根据 ID 删除记录
	/**
	  db.Delete(&User{}, 10)
	  // DELETE FROM users WHERE id = 10;
	*/
	DeleteById(id int64) bool

	// DeleteById 根据 ID 删除记录
	/**
	  // Email 的 ID 是 `10`
	  db.Delete(&email)
	  // DELETE from emails where id = 10;
	*/
	DeleteByEntityId(entity *DBId) bool

	// DeleteByIds 根据 ID 批量删除记录
	// DELETE FROM users WHERE id IN (1,2,3);
	DeleteByIds(ids ...int64) bool

	// DeleteByIds 根据 ID 批量删除记录
	// DELETE FROM users WHERE id IN (1,2,3);
	DeleteByArrayId(ids []int64) bool

	// DeleteByQuery 根据 查询条件 批量删除记录
	// DELETE FROM users WHERE id IN (1,2,3);
	DeleteByQuery(entity *T, sqlType SqlEnumsType) bool
	/*
	 *保存一条记录的方法
	 * 如果user表id为0或不存在时,执行插入语句,
	 * db.Save(&User{Name: "jinzhu", Age: 100})
	 * INSERT INTO `users` (`name`,`age`,`birthday`,`update_at`) VALUES ("jinzhu",100,"0000-00-00 00:00:00","0000-00-00 00:00:00")
	 * 如果user表id>0时,执行更新语句,
	 * db.Update(&User{ID: 1, Name: "jinzhu", Age: 100})
	 * UPDATE `users` SET `name`="jinzhu",`age`=100,`birthday`="0000-00-00 00:00:00",`update_at`="0000-00-00 00:00:00" WHERE `id` = 1
	 ***
	 ** 对象的字段为空时,不执行变更
	 */
	SaveOrUpdate(entity *T) int64

	/*
	 *保存一条记录的方法
	 * 如果user表id为0或不存在时,执行插入语句,
	 * db.Save(&User{Name: "jinzhu", Age: 100})
	 * INSERT INTO `users` (`name`,`age`,`birthday`,`update_at`) VALUES ("jinzhu",100,"0000-00-00 00:00:00","0000-00-00 00:00:00")
	 * 如果user表id>0时,执行更新语句,
	 * db.Update(&User{ID: 1, Name: "jinzhu", Age: 100})
	 * UPDATE `users` SET `name`="jinzhu",`age`=100,`birthday`="0000-00-00 00:00:00",`update_at`="0000-00-00 00:00:00" WHERE `id` = 1
	 ***
	 ** 对象的字段为空时,不执行变更
	 */
	Update(entity *T) bool

	// Update with conditions
	// Update attributes with `map`
	// db.Model(&user).Updates(map[string]T{"name": "hello", "age": 18, "active": false})
	// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
	UpdateModel(updateDate map[string]any) bool

	// SelectById 根据 ID 查询单条记录
	// SELECT * FROM users WHERE id = 10;
	SelectById(id int64) *T

	// SelectByIds 根据 ID 查询多条记录
	// SELECT * FROM `entity_company` WHERE `entity_company`.`id` IN (2,3,4)
	SelectByIds(ids []int64) *[]T

	// SelectByIds 根据 ID 查询多条记录
	// SELECT * FROM `entity_company` WHERE `entity_company`.`id` IN (2,3,4)
	SelectByIdsToMap(ids []int64) map[int64]*T

	// SelectOne 根据条件查询单条记录 ,user *model.User, sqlType gomysql.SqlEnumsType
	// SELECT count(*) FROM `entity_company` WHERE company_id = 1 AND store_code = 'Jinzhu33'
	SelectCount(entity *T, sqlType SqlEnumsType) int64
	// SelectOne 根据条件查询单条记录,默认为升序
	// SELECT * FROM `entity_company` WHERE company_id = 21 AND store_code = 'Jinzhu33'  LIMIT 1
	SelectOne(entity *T, sqlType SqlEnumsType) *T

	// SelectOne 根据条件查询单条记录
	SelectFirst(entity *T, sqlType SqlEnumsType) *T

	// SelectOne 根据条件查询单条记录
	SelectLast(entity *T, sqlType SqlEnumsType) *T

	// SelectList 根据条件查询多条记录,无分页
	// SELECT * FROM `entity_company` WHERE company_id = 21 AND store_code = 'Jinzhu33'
	SelectList(entity *T, sqlType SqlEnumsType) *[]T

	// Selectpage 根据条件查询单条记录
	// SELECT * FROM `entity_company` WHERE company_id = 21 AND store_code = 'Jinzhu33'  LIMIT 3 OFFSET 3
	SelectListByPage(entity *T, sqlType SqlEnumsType, page *QueryPage[T]) *[]T
	// Selectpage 根据条件查询单条记录
	SelectListByPageIsNext(entity *T, sqlType SqlEnumsType, page *QueryPage[T]) *QueryPage[T]

	// Selectpage 根据条件查询单条记录,统一分页列表结果规范的对象
	SelectResultListByPage(entity *T, sqlType SqlEnumsType, page *QueryPage[T]) *gomodel.ResponseResultList

	// result := GetDB().Where(q.GetWhere(), whereValue...).
	// Limit(page.GetLimit()).Offset(page.GetOffset()).Find(&entities)
	NewQuery(entity *T, sqlType SqlEnumsType) (*QueryWrapper[T], *T)
}
